package com.augurit.wf.mgmt.service.impl;

import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Hibernate;
import org.jbpm.api.Execution;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.HistoryService;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.TaskService;
import org.jbpm.api.history.HistoryActivityInstance;
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.history.HistoryTask;
import org.jbpm.api.task.Task;
import org.jbpm.jpdl.internal.activity.TaskActivity;
import org.jbpm.pvm.internal.history.model.HistoryProcessInstanceImpl;
import org.jbpm.pvm.internal.history.model.HistoryTaskImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.task.TaskImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;

import com.augurit.common.util.lang.StringUtils;
import com.augurit.wf.bi.service.IWfBusInstanceService;
import com.augurit.wf.common.dao.Jbpm4ExecutionDao;
import com.augurit.wf.common.dao.Jbpm4HistActInstDao;
import com.augurit.wf.common.dao.Jbpm4HistProcinstDao;
import com.augurit.wf.common.dao.Jbpm4TaskDao;
import com.augurit.wf.common.dao.Jbpm4VariableDao;
import com.augurit.wf.common.entity.Jbpm4Execution;
import com.augurit.wf.common.entity.Jbpm4HistActInst;
import com.augurit.wf.common.entity.Jbpm4HistProcinst;
import com.augurit.wf.common.entity.Jbpm4Task;
import com.augurit.wf.common.entity.Jbpm4Variable;
import com.augurit.wf.common.form.TraceRecord;
import com.augurit.wf.common.form.jbpm.Jbpm4TaskForm;
import com.augurit.wf.common.service.IWfService;
import com.augurit.wf.common.util.WfUtils;
import com.augurit.wf.mgmt.convert.ConvertToExtModel;
import com.augurit.wf.mgmt.convert.Jbpm4TaskConvertor;
import com.augurit.wf.mgmt.convert.Jbpm4VariableConvertor;
import com.augurit.wf.mgmt.dao.WfProcessInstanceDao;
import com.augurit.wf.mgmt.service.IWfProcessInstanceService;
import com.augurit.wf.mgmt.web.form.Jbpm4HistActInstForm;
import com.augurit.wf.mgmt.web.form.Jbpm4VariableForm;
import com.augurit.wf.mgmt.web.form.ProcInstBasicInfo;
import com.augurit.wf.mgmt.web.form.WfActivityInstanceForm;
import com.augurit.wf.mgmt.web.form.WfProcessInstanceForm;

@Service
@Transactional
public class WfProcessInstanceService implements IWfProcessInstanceService {

	@Autowired
	private ProcessEngine processEngine;
	
	@Autowired
	private IWfService wfService;

	@Autowired
	private Jbpm4VariableDao jbpm4VariableDao;
	
	@Autowired
	private Jbpm4TaskDao jbpm4TaskDao;
	
	@Autowired
	private Jbpm4HistActInstDao jbpm4HistActInstDao;
	
	@Autowired
	private WfProcessInstanceDao wfProcessInstanceDao;
	
	@Autowired
	private Jbpm4ExecutionDao jbpm4ExecutionDao;
	
	@Autowired
	private Jbpm4HistProcinstDao jbpm4HistProcinstDao;
	
	@Autowired
	private IWfBusInstanceService wfBusInstanceService;

	
	/**
	 * 查询流程实例
	 * @param page
	 * @param form
	 * @return
	 */
	@Transactional(readOnly = true)
	public Page<WfProcessInstanceForm> search(Page<WfProcessInstanceForm> page, WfProcessInstanceForm form){
		List<WfProcessInstanceForm> wfProcessInstanceForms = wfProcessInstanceDao.search(page, form);
		page.setResult(wfProcessInstanceForms);
		return page;
	}
	
	/**
	 * 删除流程实例
	 * @param processInstanceId
	 * @return
	 */
	public boolean deleteProcessInstance(String processInstanceId){
		if(processInstanceId != null){
			ExecutionService executionService = processEngine.getExecutionService();
			
			//删除业务与流程关联
			wfBusInstanceService.deleteByProcInstId(processInstanceId);
			
			executionService.deleteProcessInstanceCascade(processInstanceId);
			return true;
		}
		return false;
	}
	
	/**
	 * 挂起流程实例
	 * @param processInstanceId
	 * @return
	 */
	public boolean suspendProcessInstance(String processInstanceId){
		if(processInstanceId != null){
//			ExecutionService executionService = processEngine.getExecutionService();
//			ProcessInstance processInstance = executionService.findProcessInstanceById(processInstanceId);
//			if(processInstance != null){
//				ExecutionImpl execution = (ExecutionImpl)processInstance;
//				if(execution != null && execution.isActive()){
//					updateCasecadeState(processInstanceId,Execution.STATE_SUSPENDED);
//					return true;
//				}
//			}
			
			HistoryProcessInstance  historyProcessInstance  = processEngine.getHistoryService().createHistoryProcessInstanceQuery().processInstanceId(processInstanceId).uniqueResult();
			if(historyProcessInstance != null && HistoryProcessInstance.STATE_ACTIVE.equals(historyProcessInstance.getState())){
				updateCasecadeState(processInstanceId,Execution.STATE_SUSPENDED);
				return true;
			}
		}
		return false;
	}
	
	
	/**
	 * 恢复流程实例
	 * @param processInstanceId
	 * @return
	 */
	public boolean recoveryProcessInstance(String processInstanceId){
		if(processInstanceId != null){
			ExecutionService executionService = processEngine.getExecutionService();
			ProcessInstance processInstance = executionService.findProcessInstanceById(processInstanceId);
			if(processInstance != null && processInstance.getState().equals(Execution.STATE_SUSPENDED)){
				updateCasecadeState(processInstanceId,Execution.STATE_ACTIVE_ROOT);
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 结束流程实例
	 * @param processInstanceId
	 * @return
	 */
	public boolean endProcessInstance(String processInstanceId){
		if(processInstanceId != null){
			ExecutionService executionService = processEngine.getExecutionService();
			ProcessInstance processInstance = executionService.findProcessInstanceById(processInstanceId);
			if(processInstance != null){
				ExecutionImpl execution = (ExecutionImpl)processInstance;
				if(execution != null && execution.isActive()){
					executionService.endProcessInstance(processInstanceId, Execution.STATE_ENDED);
					return true;
				}
			}
		}
		return false;
	}
	
	
	
	
	/**
	 * 获取流程实例的所有活动实例
	 * @param processInstanceId 流程实例ID
	 * @return 流程实例的所有活动实例集合
	 */
	public List<WfActivityInstanceForm> getActsByProcInstId(String processInstanceId){
		List<WfActivityInstanceForm> wfActivityInstanceForms = new ArrayList<WfActivityInstanceForm>();
		
		if(processInstanceId != null){
			
			//获取当前流程所有历史活动实例
			HistoryService historyService = processEngine.getHistoryService();
			List<HistoryActivityInstance> histActInsts = historyService
																	.createHistoryActivityInstanceQuery()
																	.processInstanceId(processInstanceId).list();
			
			wfActivityInstanceForms = ConvertToExtModel.convertToActivityInstanceList(histActInsts, processInstanceId);
		}
		return wfActivityInstanceForms;
	}
	
	/**
	 * 获取指定节点的历史意见
	 * @param processInstanceId
	 * @param activityName
	 * @return
	 */
	public List<TraceRecord> getTraceRecord(String processInstanceId,String activityName){
		if(processInstanceId != null  && activityName != null){
			List<HistoryActivityInstance> hisActInsts = processEngine.getHistoryService()
					.createHistoryActivityInstanceQuery().processInstanceId(processInstanceId)
					.activityName(activityName).orderAsc("startTime").list();
			
			List<HistoryTask> histaskList = WfUtils.convertHisActInstListToHisTaskList(hisActInsts);
			return WfUtils.convertToTraceInfoList(histaskList);
		}
		return null;
	}
	
	//根据流程实例id获取流程实例基本信息
	public ProcInstBasicInfo getProcInstBasicInfo(String processInstanceId){
		ProcInstBasicInfo basicInfo = null;
		if(processInstanceId != null && processInstanceId.trim().length() > 0){
			HistoryProcessInstance histProcInst = processEngine.getHistoryService().createHistoryProcessInstanceQuery().processInstanceId(processInstanceId).uniqueResult();
			ProcessInstance processInstance = processEngine.getExecutionService().findProcessInstanceById(processInstanceId);
			basicInfo = WfUtils.convertToProcInstBasicInfo(histProcInst, processInstance);
		}
		return basicInfo;
	}
	
	//保存流程时限
	public void savetProcDuedate(WfProcessInstanceForm form){
		if(form != null && form.getId() != null && form.getProcessDuedate() != null){
			Jbpm4HistProcinst entity = jbpm4HistProcinstDao.getByProcinstId(form.getId());
			entity.setProcessDuedate(form.getProcessDuedate());
			jbpm4HistProcinstDao.save(entity);
		}
	}
	 //根据流程实例id获取变量表信息
	public List<Jbpm4VariableForm> getProcInstVariables(String processInstanceId){
		if(processInstanceId != null && processInstanceId.trim().length() > 0){
			List<Jbpm4Variable> list = this.jbpm4VariableDao.getVariablesByProcInstId(processInstanceId);
			return Jbpm4VariableConvertor.convertEntityListToFormList(list);
		}
		return null;
	}
	
	public void updateCasecadeState(String procInstId, String state){
		if(procInstId != null && procInstId.trim().length()>0 
				&& state != null && state.trim().length() > 0){
			
			HistoryProcessInstanceImpl hisProcInst = (HistoryProcessInstanceImpl)this.processEngine.getHistoryService()
				.createHistoryProcessInstanceQuery().processInstanceId(procInstId).uniqueResult();
			List<Jbpm4Task> jbpm4TaskList = jbpm4TaskDao.getTasksByProcInstId(procInstId);
			
			//task和HistoryProcessInstanceImpl的活动状态跟ExecutionImpl的不一样
			if(state.equals(Execution.STATE_ACTIVE_ROOT)){
				jbpm4TaskDao.updateTaskState(jbpm4TaskList, Task.STATE_OPEN);
				hisProcInst.setState(HistoryProcessInstanceImpl.STATE_ACTIVE);
			}
			else{
				jbpm4TaskDao.updateTaskState(jbpm4TaskList, state);
				hisProcInst.setState(state);
			}
			
			jbpm4ExecutionDao.updateStateByProcInstId(procInstId,state);
		}
	}
	//增加或者修改流程变量
	public void saveVariable(Jbpm4VariableForm form){
		if(form != null){
			//修改
			if(form.getDbid() != null){
				Jbpm4VariableConvertor.ConvertFormValue(form);
				jbpm4VariableDao.update(form);
			}
			//新增
			else{
				if(form.getProcInstId() != null && form.getProcInstId().trim().length()>0){
					setVariableByValueType(form.getProcInstId(),form);
				}
			}
		}
	}
	
	//根据类型保存变量
	private void setVariableByValueType(String executionId,Jbpm4VariableForm form){
		if(executionId != null && form != null && StringUtils.isNotBlank(form.getClazz())){
			ExecutionService executionService = this.processEngine.getExecutionService();
			if(form.getClazz().equals("string"))
				executionService.setVariable(executionId,form.getKey(), form.getValue());
			else if(form.getClazz().equals("long"))
				executionService.setVariable(executionId,form.getKey(), Long.parseLong(form.getValue()));
			else if(form.getClazz().equals("date"))
				try {
					executionService.setVariable(executionId,form.getKey(), DateFormat.getDateInstance().parse(form.getValue()));
				} catch (ParseException e) {
					e.printStackTrace();
				}
			else if(form.getClazz().equals("double"))
				executionService.setVariable(executionId,form.getKey(),Double.parseDouble(form.getValue()));
		}
	}
	//根据dbid获取Jbpm4VariableForm对象
	public Jbpm4VariableForm getVariable(Long dbid){
		if(dbid != null)
			return jbpm4VariableDao.getForm(dbid);
		return null;
	}
	
	//批量删除流程变量
	public void deleteVariables(Long... varDbids){
		if(varDbids != null){
			jbpm4VariableDao.delete(varDbids);
		}
	}
	
	//************************控制活动实例  开始************************
	
	/**
	 * 根据活动实例ID获取Jbpm4HistActInstForm活动实例对象
	 *@param actInstDbid
	 *@return 
	 */
	public Jbpm4HistActInstForm getActInstByDbid(Long actInstDbid){
			return jbpm4HistActInstDao.getForm(actInstDbid);
	}
	
	/**
	 * 根据活动实例ID获取活动实例任务列表
	 * @param actInstDbid
	 * @return
	 */
	public List<Jbpm4TaskForm> getTasksByActInstDbid(Long actInstDbid){
		List<Jbpm4TaskForm> jbpm4TaskForms = null;
		if(actInstDbid != null){
			List<Jbpm4Task> jbpm4Tasks = this.jbpm4TaskDao.getTasksByActInstDbid(actInstDbid);
//			//将state转化为中文
//			Jbpm4TaskConvertor.convertStateToChinese(list);
			jbpm4TaskForms = Jbpm4TaskConvertor.convertToFormList(jbpm4Tasks);
		}
		return jbpm4TaskForms;
	}
	
	/**
	 * 完成活动实例
	 * @param processInstanceId
	 * @param actInstId
	 */
	public void completeActInst(Long actInstDbid){
		if(actInstDbid != null){
			
		}
	}
	
	/**
	 * 终止活动实例
	 * @param multitaskTaskIds 终止的任务数据库ID集合
	 * @return 终止成功时返回true
	 */
	public void endActInst(List<Long> multitaskTaskIds){
		if(multitaskTaskIds.size() > 1){
			String taskId = multitaskTaskIds.get(0).toString();
			Task task = this.processEngine.getTaskService().getTask(taskId);
			String executionId = task.getExecutionId();
			
			Map<String,Task> param = new HashMap<String,Task>();
			param.put(TaskActivity.CUR_TASK, task);
			
			this.processEngine.getExecutionService().signalExecutionById(executionId,param);
		}
		
		
		//修改历史记录的状态为废弃
		wfProcessInstanceDao.updateHistoryTaskState(HistoryTask.STATE_OBSOLETE, multitaskTaskIds);
	}
	
	/**
	 * 挂起活动实例
	 * @param actInstDbid
	 */
	public boolean suppendActInst(Long actInstDbid){
		if(actInstDbid != null){
			Jbpm4HistActInst jbpm4HistActInst = this.jbpm4HistActInstDao.get(actInstDbid);
			String executionId  = jbpm4HistActInst.getExecutionId();
			ExecutionImpl execution = (ExecutionImpl)this.processEngine.getExecutionService().findExecutionById(executionId);
			if(execution != null && execution.isActive()){
				//将活动实例的所有task挂起
				updateTasksByExecutionId(executionId,Task.STATE_SUSPENDED);
				
				//挂起活动实例对应的execution状态
				execution.setState(Execution.STATE_SUSPENDED);
				return true;
			}
		}
		return false;
	}
	
	
	
	/**
	 * 恢复活动实例
	 * @param processInstanceId
	 * @param actInstId
	 */
	public boolean recoveryActInst(Long actInstDbid){
		if(actInstDbid != null){
			Jbpm4HistActInst jbpm4HistActInst = this.jbpm4HistActInstDao.get(actInstDbid);
			String executionId  = jbpm4HistActInst.getExecutionId();
			ExecutionImpl execution = (ExecutionImpl)this.processEngine.getExecutionService().findExecutionById(executionId);
			if(execution != null && execution.isSuspended()){
				//将活动实例的所有task恢复
				updateTasksByExecutionId(executionId,Task.STATE_OPEN);
				
				
				//挂起活动实例对应的execution状态
				if(execution.getIsProcessInstance())
					execution.setState(Execution.STATE_ACTIVE_ROOT);
				else
					execution.setState(Execution.STATE_ACTIVE_CONCURRENT);
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 根据执行ID查找当前任务ID，如果是多任务，就找出主任务
	 * @param executionId 执行ID
	 * @param activityInstanceDbid 活动实例DBID
	 * @return 任务
	 */
	public Task getTaskIdByExecutionId(String executionId,Long activityInstanceDbid){
		Jbpm4HistActInst jbpm4HistActInst = jbpm4HistActInstDao.get(activityInstanceDbid);
		if(jbpm4HistActInst != null){
			//判断当前如果是state类型的实例，就直接推进到下一个节点
			if("state".equals(jbpm4HistActInst.getType())){
				this.processEngine.getExecutionService().signalExecutionById(executionId);
			}else{
				List<Task> tasks = this.processEngine.getTaskService().createTaskQuery().executionId(executionId).list();
				
				if(tasks != null){
					if(tasks.size() == 1){
						return tasks.get(0);
					}else if(tasks.size() > 1){
						for (Task task : tasks) {
							if(((TaskImpl)task).getSuperTask() == null)
								return task;
						}
					}
				}
			}
		}
			
		return null;
	}
	
	/**
	 * 根据父任务ID获取其子任务ID
	 * @param superTaskId 父任务ID
	 * @return 包含父任务ID在内的其所属任务ID
	 */
	public List<Long> getMultitaskTaskIdsBySuperTaskId(Long superTaskId){
		List<Long> multitaskTaskIds = new ArrayList<Long>();
		multitaskTaskIds.add(superTaskId);
		
		HistoryTaskImpl hisTask = (HistoryTaskImpl)this.processEngine.getHistoryService().createHistoryTaskQuery().taskId(superTaskId.toString()).uniqueResult();
		Set<HistoryTaskImpl> subTasks = hisTask.getSubTasks();
		for (HistoryTaskImpl historyTaskImpl : subTasks) {
			multitaskTaskIds.add(new Long(historyTaskImpl.getId()));
		}
		return multitaskTaskIds;
	}
	
	/**
	 * 根据活动实例ID获取任务ID，如果此活动为多工作项，或者是状态，就直接完成到下一步。
	 * @param actInstDbid 活动实例ID
	 * @return 任务ID
	 */
	public Long getTaskByActInstDbid(Long actInstDbid){
		if(actInstDbid != null){
			Jbpm4HistActInst jbpm4HistActInst = jbpm4HistActInstDao.get(actInstDbid);
			
			//state节点
			if(jbpm4HistActInst != null && "state".equals(jbpm4HistActInst.getType())){
				ExecutionService executionService = this.wfService.getProcessEngine().getExecutionService();
				
				ExecutionImpl execution = (ExecutionImpl)executionService.findExecutionById(jbpm4HistActInst.getExecutionId());
				executionService.signalExecutionById(execution.getId());
			}
			
			//task节点
			else{
				List<Task> list = getTasks(actInstDbid);
				
				if(list != null && list.size()>0){
					TaskImpl firstTask =(TaskImpl)list.get(0);
					
					//多工作项，直接完成
					if(list.size()>1){
						this.processEngine.getTaskService().completeMultTaskByAdmin(firstTask.getExecutionId());
					}
					//普通任务
					else
						return firstTask.getDbid();
				}
			}
		}
		return null;
	}
	
	public List<Task> getTasks(Long actInstDbid){
		List<Task> list = null;
		if(actInstDbid != null){
			Jbpm4HistActInst jbpm4HistActInst = jbpm4HistActInstDao.get(actInstDbid);
			String executionId = jbpm4HistActInst.getExecutionId();
			
			TaskService taskService = this.processEngine.getTaskService();
			list  = taskService.createTaskQuery().executionId(executionId).list();
		}
		return list;
	}
	
	/**
	 * 当前活动是否可以前进到下一个节点
	 * @param executionId 活动对应的executionId
	 * @return true代表可以
	 */
	public boolean isSign(String executionId){
		Execution execution = this.processEngine.getExecutionService().findExecutionById(executionId);
		if(execution != null && execution.getState().indexOf("active") != -1)
			return true;
		return false;
	}
	
	/**
	 * 根据活动实例ID和活动名进行回退，只支持回退到上一个节点
	 * @param executionId 当前活动执行ID
	 * @return 回退成功时返回true，否则返回false
	 * @throws Exception 
	 */
	public boolean rollbackActivityInstance(String executionId) throws Exception{
		if(executionId != null && executionId.trim().length() > 0){
			//如果当前处于挂起状态，就不能回退。
			Execution execution = this.processEngine.getExecutionService().findExecutionById(executionId);
			if(Execution.STATE_SUSPENDED.equals(execution.getState()))
				return false;
			
			List<Task> list = this.processEngine.getTaskService().createTaskQuery().executionId(executionId).list();
			if(list != null && list.size() == 1){
				TaskImpl task = (TaskImpl)list.get(0);
				return wfService.returnPrevTask(task.getDbid());
			}
		}
		return false;
	}
	
	//************************控制活动工实例  结束************************
	
	//************************控制活动工作项  开始************************
	
	
	//创建工作项,只有多工作项的任务活动实例才可以动态创建工作项
	public boolean addSubTask(Long hisActInstDbid, String assignee){
		TaskImpl superTask = getSuperTaskByActInstId(hisActInstDbid);
		if(superTask != null){
			this.processEngine.getTaskService().createSubMultiTasksInRumtime(assignee, superTask);
			return true;
		}
		return false;
	}
	
	//删除工作项,只有多工作项的任务活动实例才可以动态删除工作项
	public boolean delSubTask(String taskId){
		if(taskId != null){
			TaskService taskService = this.processEngine.getTaskService();
			TaskImpl subTask = (TaskImpl)taskService.getTask(taskId);
			
			if( subTask != null && WfUtils.isMultiTask(subTask) && subTask.getSuperTask() != null ){
				taskService.delSubTask(taskId);
				return true;
			}
		}
		return false;
	}

	
	/**
	 * 根据流程实例ID和活动实例状态获取当前活动实例集合
	 * @param processInstanceId 流程实例ID
	 * @param state 活动实例状态
	 * @return 当前活动实例集合
	 */
	public List<Jbpm4Execution> getCurrentActivityInstancesByProcessInstanceId(Long processInstanceId){
//		if("active".equals(state) || 
//			"inactive-concurrent-root".equals(state) ||
//			"active-root".equals(state) ||
//			"active-concurrent".equals(state)){
//			
//			state = WfProcessInstanceDao.EXECUTION_STATE_ACTIVE;
//		}else{
//			state = WfProcessInstanceDao.EXECUTION_STATE_SUSPENDED;
//		}
//		
		List<Jbpm4Execution> jbpm4Executions = wfProcessInstanceDao.getCurrentActivityInstancesByProcessInstanceId(processInstanceId);
		return jbpm4Executions;
	}
	
	/**
	 * 获取相应流程实例下的所有活动实例
	 * @param page 
	 * @param form
	 * @return
	 */
	public List<WfActivityInstanceForm> getActInstsByActivityName(WfProcessInstanceForm form){
		List<WfActivityInstanceForm> list = null;
		if(form != null && form.getId() != null && StringUtils.isNotBlank(form.getActivityName())){
			List<HistoryActivityInstance> histActInsts = processEngine.getHistoryService()
			.createHistoryActivityInstanceQuery().processInstanceId(form.getId())
			.activityName(form.getActivityName()).list();
			
			list = ConvertToExtModel.convertToActivityInstanceList(histActInsts,form.getId());
		}
		return list;
	}
	
	/**
	 * 根据流程实例ID获取流程实例
	 * @param processInstanceId 流程实例ID
	 * @return 流程实例
	 */
	public ProcessInstance getProcessInstancesById(String processInstanceId){
		ProcessInstance processInstance = processEngine.getExecutionService().findProcessInstanceById(processInstanceId);
		return processInstance;
	}
	
	/**
	 * 根据流程实例ID获取历史流程实例
	 * @param processInstanceId 流程实例ID
	 * @return 流程实例
	 */
	public HistoryProcessInstanceImpl getHisProcessInstancesById(String processInstanceId){
		HistoryProcessInstance historyProcessInstance = processEngine.getHistoryService().createHistoryProcessInstanceQuery().processInstanceId(processInstanceId).uniqueResult();
		if(historyProcessInstance != null)
			return (HistoryProcessInstanceImpl)historyProcessInstance;
		return null;
	}
	
	/**
	 * 根据任务ID获取流程实例
	 * @param taskId 任务ID
	 * @return 流程实例
	 */
	public HistoryProcessInstanceImpl getProcessInstancesByTaskDbid(String taskId){
		String executionId = processEngine.getTaskService().getTask(taskId).getExecutionId();
		ProcessInstance processInstance = (ProcessInstance)processEngine.getExecutionService().findExecutionById(executionId).getProcessInstance();
		HistoryProcessInstance historyProcessInstance = processEngine.getHistoryService().createHistoryProcessInstanceQuery().processInstanceId(processInstance.getId()).uniqueResult();
		if(historyProcessInstance != null)
			return (HistoryProcessInstanceImpl)historyProcessInstance;
		return null;
	}
	
	//取消代办
	public void cancelAgentTask(Long taskInstDbid){
		if(taskInstDbid != null ){
			Jbpm4Task jbpm4Task =  jbpm4TaskDao.get(taskInstDbid);
			
			jbpm4Task.setAgent(null);
			jbpm4Task.setAgentName(null);
			jbpm4Task.setAgentStartDate(null);
			jbpm4Task.setAgentEndDate(null);
			
			HistoryTaskImpl histask = this.getHistoryTaskImpl(taskInstDbid.toString());
			histask.setAgent(null);
			histask.setAgentName(null);
			histask.setAgentStartDate(null);
			histask.setAgentEndDate(null);
			
			try {
				wfProcessInstanceDao.updateTask(jbpm4Task);
				wfProcessInstanceDao.updateHisTask(histask);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
	}
	
	public Jbpm4TaskForm getTaskByDbid(Long taskInstDbid){
		Jbpm4TaskForm form = null;
		if(taskInstDbid != null){
			Jbpm4Task entity =  jbpm4TaskDao.get(taskInstDbid);
			form = Jbpm4TaskConvertor.convertToForm(entity);
		}
		return form;
	}

	/**
	 * 根据ID返回任务对象
	 * @param taskInstDbid 任务DBID
	 * @return 返回任务对象
	 */
	public Jbpm4Task getJbpm4TaskByDbid(Long taskInstDbid){
		if(taskInstDbid != null){
			Jbpm4Task jbpm4Task =  jbpm4TaskDao.get(taskInstDbid);
			Hibernate.initialize(jbpm4Task);
			return jbpm4Task;
		}
		return null;
	}
	
	/**
	 * 根据ID返回任务对象
	 * @param taskInstDbid 任务DBID
	 * @return 返回任务对象
	 */
	private HistoryTaskImpl getHistoryTaskImpl(String historyTaskImplDbid){
		if(historyTaskImplDbid != null){
			HistoryTaskImpl historyTaskImpl = (HistoryTaskImpl)this.processEngine.getHistoryService().createHistoryTaskQuery().taskId(historyTaskImplDbid).uniqueResult();
			return historyTaskImpl;
		}
		return null;
	}
	
	/**
	 * 修改当前任务和历史任务
	 * @param jbpm4Task 要修改的任务对象
	 * @return 返回修改结果，true时代表修改成功
	 */
	public boolean updateTask(Jbpm4Task jbpm4Task)throws Exception{
		HistoryTaskImpl historyTaskImpl = this.getHistoryTaskImpl(jbpm4Task.getTaskInstDbid().toString());
		historyTaskImpl.setAssigneeName(jbpm4Task.getAssigneeName());
		historyTaskImpl.setAssignee(jbpm4Task.getAssignee());
		historyTaskImpl.setHandleComments(jbpm4Task.getHandleComments());
		historyTaskImpl.setHandleCommentsTime(jbpm4Task.getHandleCommentsTime());
		historyTaskImpl.setAgent(jbpm4Task.getAgent());
		historyTaskImpl.setAgentName(jbpm4Task.getAgentName());
		historyTaskImpl.setAgentStartDate(jbpm4Task.getAgentStartDate());
		historyTaskImpl.setAgentEndDate(jbpm4Task.getAgentEndDate());
		
		wfProcessInstanceDao.updateTask(jbpm4Task);
		wfProcessInstanceDao.updateHisTask(historyTaskImpl);
		return true; 
	}
	//************************控制活动工作项  结束************************
	
	//修改Execution对应的所有task状态
	private void updateTasksByExecutionId(String executionId,String state){
		if(executionId != null && state != null){
			
			//将活动实例的所有task挂起
			TaskService taskService = this.processEngine.getTaskService();
			List<Task> list = taskService.createTaskQuery().executionId(executionId).list();
			if(list != null){
				for(Task task :list){
					TaskImpl taskImpl = (TaskImpl)task;
					taskImpl.setState(state); 
					taskService.saveTask(taskImpl);
				}
			}
		}
	}
	private TaskImpl getSuperTaskByActInstId(Long hisActInstDbid){
		TaskImpl superTask = null;
		if(hisActInstDbid != null){
			Jbpm4HistActInst jbpm4HistActInst = this.jbpm4HistActInstDao.get(hisActInstDbid);
			if(jbpm4HistActInst != null && jbpm4HistActInst.getHisTaskDbid() != null){
				String superTaskId = jbpm4HistActInst.getHisTaskDbid().toString();
				superTask = (TaskImpl)this.processEngine.getTaskService().getTask(superTaskId);
			}
		}
		return superTask;
	}
	
}